/**
 * 文件名：@AbstractRequestBodyEncoder.java <br/>
 * 包名：cn.efunbox.afw.soa.client.netflix.feign.support <br/>
 * 项目名：afw-soa <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.soa.client.netflix.feign.support;

import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;

/**
 * 类名：AbstractRequestBodyEncoder  <br />
 *
 * 功能：将请求参数放到请求体里面，与方法参数一一对应的编码器，该编码器会将请求参数按顺序放到List中
 *
 * @author xtwin <br />
 * 创建时间：2016年7月24日 下午3:30:00  <br />
 * @version 2016年7月24日
 */
public abstract class AbstractRequestBodyEncoder implements Encoder {
	
	// 字符集
	protected Charset charset = Charset.forName("UTF-8");
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年7月24日 下午3:30:11<br/>
	 * 
	 * @param object
	 * @param bodyType
	 * @param template
	 * @throws EncodeException <br/>
	 * @see feign.codec.Encoder#encode(java.lang.Object, java.lang.reflect.Type, feign.RequestTemplate)
	 */
	@Override
	public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
		if (object instanceof Map) {
			// 所有参数，注意：这里只包含非null得参数，参考：feign.ReflectiveFeign.BuildTemplateByResolvingArgs.create(Object[])
			@SuppressWarnings("unchecked")
			Map<String, Object> datas = (Map<String, Object>) object;
			
			List<Object> list = new ArrayList<>();
			
			if (! datas.isEmpty()) {
				// 找出最大的索引值
				int max = Integer.parseInt(Collections.max(datas.keySet()));
				
				// 依次将每个参数放入集合中
				for (int i = 0, len = max + 1; i < len; i++) {
					list.add(datas.get(String.valueOf(i)));
				}
			}
			
			template.header("Content-Type", "application/json;charset=UTF-8");
			//template.body(JSON.toJSONString(list));
			
			String body = doEncode(object, bodyType, template, list);
			if (null != body) {
				template.body(body.getBytes(charset), charset);
			}
		} else {
			throw new RuntimeException("type is not support : " + bodyType);
		}
	}
	
	/**
	 * 功能： <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月24日 下午3:35:32 <br/>
	 */
	protected abstract String doEncode(Object object, Type bodyType, RequestTemplate template, List<Object> data);
	
	/**
	 * @version 2016年7月24日-下午3:41:28
	 */
	public void setCharset(Charset charset) {
		this.charset = charset;
	}
}
